import os
import subprocess
from seleniumbase import BaseCase
from seleniumbase import SB
BaseCase.main(__name__, __file__)


class UCPresentationClass(BaseCase):
    def test_presentation(self):
        self.open("data:,")
        self.create_presentation(theme="beige", transition="fade")
        self.add_slide(
            "<p>A deep dive into <b>undetectable automation</b>, with:</p>"
            "<h5><code>SeleniumBase UC Mode"
            " and undetected-chromedriver</code></h5>",
            image="https://seleniumbase.io/cdn/img/uc_mode_phases_3.png",
        )
        self.add_slide(
            '<img src="https://seleniumbase.io/cdn/img/uc_mode_phases_3.png">'
        )
        self.add_slide(
            "<p>🔹 <b>The Objective</b> 🔹</p><hr /><br />"
            "<p><mk-0>By the end of this presentation, you'll learn how to"
            " create bots that appear as humans to websites.</mk-0></p><br />"
            "<p><mk-1>(These bots won't get detected or blocked.)</mk-1></p>"
            "<br /><p><mk-2>Here's a live demo of that...</mk-2></p>"
        )
        self.begin_presentation(filename="uc_presentation.html")

        self.get_new_driver(undetectable=True)
        try:
            self.driver.uc_open_with_reconnect(
                "https://nowsecure.nl/#relax", reconnect_time=3
            )
            try:
                self.assert_text("OH YEAH, you passed!", "h1", timeout=4)
                self.post_message("Selenium wasn't detected!", duration=4)
            except Exception:
                self.clear_all_cookies()
                self.driver.uc_open_with_reconnect(
                    "https://nowsecure.nl/#relax", reconnect_time=3
                )
                self.assert_text("OH YEAH, you passed!", "h1", timeout=4)
                self.post_message("Selenium wasn't detected!", duration=4)
        finally:
            self.quit_extra_driver()

        if os.path.exists("multi_uc.py"):
            self.create_presentation(theme="beige", transition="fade")
            self.add_slide(
                "<p>🔹 <b>There's a lot more to come!</b> 🔹</p><hr /><br />"
                "<p><mk-0>If one bot isn't enough, how about several?</mk-0>"
                "</p><br /><br />"
                "<p><mk-1>Here's a demo of multithreaded bots in parallel..."
                "</mk-1></p>"
            )
            self.begin_presentation(filename="uc_presentation.html")
            subprocess.Popen("pytest multi_uc.py --uc -n3", shell=True).wait()
            self.create_presentation(theme="serif", transition="fade")
            self.add_slide(
                "<p>Not just an army of bots, but an army of bots<br />"
                "that look just like humans using web browsers.</p><br />"
                "<p>(That's how they weren't detected!)</p>"
            )
            self.begin_presentation(filename="uc_presentation.html")

        self.create_presentation(theme="serif", transition="fade")
        self.add_slide(
            "If this is what you came here for, stick around<br />to"
            " learn how to do the things you just saw.<br />"
            "<p>You may find it easier to build a Selenium<br />"
            "bot than to navigate an obstacle course.</p>",
            image="https://seleniumbase.io/other/yeah_you_passed.png",
        )
        self.add_slide(
            "<p>But first, you may be wondering who I am...</p>"
            "<p>Or maybe you're one of over one million people<br />"
            "that I've already helped on Stack Overview:</p>"
            '<img src="https://seleniumbase.io/other/me_st_overflow.jpg" '
            'width="80%">'
        )
        self.add_slide(
            "<p><b>About the presenter (Michael Mintz):</b></p>\n"
            "<ul>\n"
            "<li>I created <b>SeleniumBase</b> (for Python).</li>\n"
            "<li>I lead the Automation Team at <b>iboss</b>.</li>\n"
            "</ul>\n",
            image="https://seleniumbase.io/other/iboss_booth.png",
        )
        self.add_slide(
            "<p>I've been doing video podcasts since 2012!</p>"
            "<p>(That's when I first co-hosted the<br />Marketing Update"
            " on HubSpot TV)</p>",
            image="https://seleniumbase.io/other/hub_tv.png",
        )
        self.add_slide(
            "<p>I spoke at Selenium Conference 2023:</p>"
            "<p>(As the dedicated Python Selenium speaker)</p>",
            image="https://seleniumbase.io/other/me_se_conf.jpg",
        )
        self.add_slide(
            "<p>Here's me with the creators<br />"
            "of <b>Selenium</b> / <b>WebDriver</b>:</p>",
            image="https://seleniumbase.io/other/selenium_builders.jpg",
        )
        self.add_slide(
            "<b>SeleniumBase</b> Fun Fact:"
            "<div />The 1st SB GitHub issue was from a Tesla engineer:",
            image="https://seleniumbase.io/other/first_issue.png",
        )
        self.add_slide(
            "<p>Now, let me explain how we got here...</p>"
            "<p>And by here, I mean a time when lots of companies"
            " have been building services to detect and block bots:</p>",
            image="https://seleniumbase.io/other/verify_human.png",
        )
        self.add_slide(
            "<p>In the early days, there were few bots,<br />"
            "and those bots didn't look human at all.</p><br />"
            "<p>Those early bots were mostly innocent, and<br />"
            "most websites didn't care if they were around.</p>"
        )
        self.add_slide(
            "<p>At some point, the number of bots grew by a lot...</p><br />"
            "<p>Many bots were programmed with bad intentions...</p><br />"
            "<p>And sometimes you couldn't tell apart the good bots"
            " from the bad ones until it was already too late...</p>",
        )
        self.add_slide(
            "<p>Then came Google <b>reCAPTCHA v1</b>...</p>"
            "<p>Although intended as a defense against bots,<br />"
            " humans on a web browser also got hit by it.</p>",
            image="https://seleniumbase.io/other/recaptcha_v1.png",
        )
        self.add_slide(
            "<p>Then Google made improvements:</p>"
            "<p>(<b>reCAPTCHA v2</b> / <b>reCAPTCHA v3</b>)</p>",
            image="https://seleniumbase.io/other/recaptcha_v2a.png",
        )
        self.add_slide(
            "<p>And that annoyed a lot of people...</p>",
            image="https://seleniumbase.io/other/recaptcha_v2b.png",
        )
        self.add_slide(
            "<p>Then came the next iteration of anti-bot security:</p>"
            "<p>Cloudflare <b>Turnstile</b> CAPTCHA-replacement."
            "<p>That changed the game in many ways.</p>",
            image="https://seleniumbase.io/other/check_if_secure.png",
        )
        self.add_slide(
            "For awhile, Cloudflare's Turnstile did a decent<br />"
            "job filtering out bot traffic from human traffic."
            "<p>Then <code>undetected-chromedriver</code> arrived:</p>",
            image="https://seleniumbase.io/other/undetected_ch.png",
        )
        self.add_slide(
            '<img src="https://seleniumbase.io/other/undetected_ch.png" '
            'width="90%">'
        )
        self.add_slide(
            "<p><code>undetected-chromedriver</code> was found to be<br />"
            "incredibly effective at getting past the Turnstile:</p>",
            image="https://seleniumbase.io/other/connection_secure.png",
        )
        self.add_slide(
            "<p>The maintainer of <code>undetected-chromedriver</code>:</p>"
            "<hr /><p>He appears to be very busy with various projects.</p>"
            '<img src="https://seleniumbase.io/other/the_uc_starter.png" '
            'width="80%">'
        )
        self.add_slide(
            "<p>The biggest challenge for undetected-chromedriver"
            " has been adapting to breaking changes caused by:</p><div />"
            "<ul>\n"
            "<li>New versions of Chrome.</li>\n"
            "<li>New versions of Selenium.</li>\n"
            "<li>New versions of Cloudflare.</li>\n"
            "</ul><br /><hr />\n"
            "<p>Those can brake things until updates are released:</p>"
            '<img src="https://seleniumbase.io/other/uc_open_issues.png" '
            'width="80%">'
        )
        self.add_slide(
            "<p>Thankfully, <code>undetected-chromedriver</code> has<br />"
            "supporters helping to figure out and fix things.<p>"
            '<img src="https://seleniumbase.io/other/uc_helping_out.png" '
            'width="70%">'
        )
        self.add_slide(
            "<h4>Sometimes all that help isn't enough...</h4>"
            "<p>That's where <code>seleniumbase</code> UC Mode comes in:</p>"
            '<img src="https://seleniumbase.io/other/sb_github.png" '
            'width="70%">'
        )
        self.add_slide(
            "<h4>SeleniumBase <b>UC Mode</b> is a modified fork of<br />"
            "undetected-chromedriver with multiple changes.</h4>"
            "<h4>UC Mode includes bug fixes and additional features, such as"
            " multithreading support via <code>pytest-xdist</code>.</h4>"
            '<img src="https://seleniumbase.io/other/super_server.jpg" '
            'width="60%">'
        )
        self.add_slide(
            "<h4><mk-0><b>UC Mode</b> is one of many SeleniumBase modes:"
            "</mk-0></h4>\n<ul>\n"
            "<li><mk-1>UC Mode</mk-1> (<code>--uc / uc=True</code>)</li>\n"
            "<li><mk-2>Slow Mode</mk-2> (<code>--slow</code>)</li>\n"
            "<li><mk-3>Demo Mode</mk-3> (<code>--demo</code>)</li>\n"
            '<li><mk-4>Proxy Mode</mk-4>'
            ' (<code>--proxy="h:p"/"u:p@h:p"</code>)</li>\n'
            "<li><mk-5>Debug Mode</mk-5> "
            "(<code>--pdb/--trace/--ftrace</code>)</li>\n"
            "<li><mk-6>Mobile Mode</mk-6> "
            "(<code>--mobile / mobile=True)</code></li>\n"
            "<li><mk-7>Recorder Mode</mk-7> "
            "(<code>--rec / --rec-behave</code>)</li>\n"
            "<li><mk-8>Multithreaded Mode</mk-8> "
            "(<code>pytest -n4 / -n8</code>)</li>\n"
            "</ul>\n"
            "<p><mk-9>And more! (You can even combine modes!)</mk-9></p>\n"
        )
        self.add_slide(
            "<p><mk-0>ℹ️: UC Mode is not enabled by default.<br />"
            " It must be activated by switching it on:</mk-0></p>"
            "<ul>\n"
            "<li><code><mk-1>--uc</mk-1></code> &nbsp"
            " (pytest command-line option)</li>\n"
            "<li><code><mk-2>uc=True</mk-2></code> &nbsp"
            " (SB/driver manager formats)</li>\n"
            "</ul><br /><br /><hr /><br />\n<p>"
            "<mk-3>Then websites can no longer detect chromedriver.</mk-3></p>"
        )
        self.add_slide(
            "<p><mk-0>Here's an example script that uses UC Mode:</mk-0></p>\n"
            "<h5><mk-1>(Note that SeleniumBase has <code>driver</code> methods"
            "<br />that aren't included with standard Selenium.)</mk-1></h5>\n"
            "<hr /><br />\n",
            code=(
                "<mk-2>from seleniumbase import Driver</mk-2>\n\n"
                "<mk-3>driver = Driver(uc=True)</mk-3>\n"
                "<mk-4>try:</mk-4>\n"
                '    <mk-5>driver.get("https://nowsecure.nl/#relax")</mk-5>\n'
                "    <mk-1><mk-6>driver.sleep(4)</mk-6></mk-1>\n"
                "    <mk-7># DO MORE STUFF</mk-7>\n"
                "<mk-4>finally:</mk-4>\n"
                "    <mk-4>driver.quit()</mk-4>\n"
            ),
        )
        self.add_slide(
            "<p><mk-0>For reference, here's a script in a different<br />"
            "SeleniumBase format, with more methods:</mk-0></p>"
            "<h5><mk-12>(Get ready for another live demo...)</mk-12></h5>",
            code=(
                "<mk-1>from seleniumbase import SB</mk-1>\n\n"
                "<mk-2>with SB(uc=True) as sb:</mk-2>\n"
                '    <mk-3>sb.driver.get('
                '"https://seleniumbase.io/simple/login")</mk-3>\n'
                '    <mk-4>sb.type("#username", "demo_user")</mk-4>\n'
                '    <mk-5>sb.type("#password", "secret_pass")</mk-5>\n'
                '    <mk-6>sb.click(\'a:contains("Sign in")\')</mk-6>\n'
                '    <mk-7>sb.assert_exact_text("Welcome!", "h1")</mk-7>\n'
                '    <mk-8>sb.assert_element("img#image1")</mk-8>\n'
                '    <mk-9>sb.highlight("#image1")</mk-9>\n'
                '    <mk-10>sb.click_link("Sign out")</mk-10>\n'
                '    <mk-11>sb.assert_text("signed out", "#top_message")'
                "</mk-11>\n"
            ),
        )
        self.begin_presentation(filename="uc_presentation.html")

        try:
            with SB(uc=True) as sb:
                sb.driver.get("https://seleniumbase.io/simple/login")
                sb.type("#username", "demo_user")
                sb.type("#password", "secret_pass")
                sb.click('a:contains("Sign in")')
                sb.assert_exact_text("Welcome!", "h1")
                sb.assert_element("img#image1")
                sb.highlight("#image1")
                sb.click_link("Sign out")
                sb.assert_text("signed out", "#top_message")
        except Exception:
            pass

        self.create_presentation(theme="serif", transition="fade")
        self.add_slide(
            "<h3><mk-0>Was that too fast for you?</mk-0></h3>"
            "<h4><mk-1>Let's run that again in <b>Demo Mode</b>:</mk-1></h4>",
            code=(
                "from seleniumbase import SB\n\n"
                "with SB(uc=True<mk-1>, demo=True</mk-1>) as sb:\n"
                '    sb.driver.get('
                '"https://seleniumbase.io/simple/login")\n'
                '    sb.type("#username", "demo_user")\n'
                '    sb.type("#password", "secret_pass")\n'
                '    sb.click(\'a:contains("Sign in")\')\n'
                '    sb.assert_exact_text("Welcome!", "h1")\n'
                '    sb.assert_element("img#image1")\n'
                '    sb.highlight("#image1")\n'
                '    sb.click_link("Sign out")\n'
                '    sb.assert_text("signed out", "#top_message")\n'
            ),
        )
        self.begin_presentation(filename="uc_presentation.html")

        try:
            with SB(uc=True, demo=True) as sb:
                sb.driver.get("https://seleniumbase.io/simple/login")
                sb.type("#username", "demo_user")
                sb.type("#password", "secret_pass")
                sb.click('a:contains("Sign in")')
                sb.assert_exact_text("Welcome!", "h1")
                sb.assert_element("img#image1")
                sb.highlight("#image1")
                sb.click_link("Sign out")
                sb.assert_text("signed out", "#top_message")
        except Exception:
            pass

        self.create_presentation(theme="serif", transition="fade")
        self.add_slide(
            "<p><mk-0>Note the differences between undetected-chromedriver and"
            " SeleniumBase UC Mode.</mk-0><br /><hr />SeleniumBase UC Mode:"
            "</p><ul>\n"
            "<li><mk-1>Has driver version-detection & management.</mk-1>"
            "</li>\n"
            "<li><mk-2>Allows mismatched browser/driver versions.</mk-2>"
            "</li>\n"
            "<li><mk-3>Changes the user agent to prevent detection.</mk-3>"
            "</li>\n"
            "<li><mk-4>Hides chromedriver from Chrome as needed.</mk-4>"
            "</li>\n"
            "<li><mk-5>Allows for multithreaded tests in parallel.</mk-5>"
            "</li>\n"
            "<li><mk-6>Adjusts configuration based on the environment.</mk-6>"
            "</li>\n"
            "<li><mk-7>Has options for proxy and proxy-with-auth.</mk-7>"
            "</li>\n</ul>\n"
        )
        self.add_slide(
            "<h3><mk-0>Here's another UC Mode script:</mk-0></h3>"
            "<h4><mk-1>(Get ready for another live demo...)</mk-1></h4>"
            "<hr /><br />",
            code=(
                "from seleniumbase import SB\n\n"
                "with SB(uc=True) as sb:\n"
                '    sb.driver.get("https://nowsecure.nl/#relax")\n'
                "    sb.sleep(1)\n"
                '    if not sb.is_text_visible("OH YEAH, you passed", "h1"):\n'
                "        sb.get_new_driver(undetectable=True)\n"
                '        sb.driver.get("https://nowsecure.nl/#relax")\n'
                "        sb.sleep(1)\n"
                '    sb.activate_demo_mode()\n'
                '    sb.assert_text("OH YEAH, you passed!", "h1", timeout=3)\n'
            ),
        )
        self.begin_presentation(filename="uc_presentation.html")

        try:
            with SB(uc=True) as sb:
                sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
                sb.sleep(1)
                if not sb.is_text_visible("OH YEAH, you passed", "h1"):
                    sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
                    sb.sleep(1)
                sb.activate_demo_mode()
                sb.assert_text("OH YEAH, you passed!", "h1", timeout=3)
        except Exception:
            pass

        self.create_presentation(theme="serif", transition="fade")
        self.add_slide(
            "<p>Now let's learn how UC Mode works in general.</p>"
            "<p>First, there are several things that need to happen for"
            " browsers to remain undetected from anti-bot services.</p>\n",
            image="https://seleniumbase.io/other/yeah_you_passed.png",
        )
        self.add_slide(
            "<mk-0>Requirements for avoiding detection</mk-0> (UC Mode)<hr />"
            "<ul>\n"
            "<li><mk-1>Modify chromedriver to rename driver variables"
            " that appear in the Chrome DevTools console.</mk-1></li>\n"
            "<li><mk-2>Launch Chrome before attaching chromedriver.<br />"
            "(Don't launch Chrome with chromedriver)</mk-2></li>\n"
            "<li><mk-3>Don't use Selenium-specific Chrome options.</mk-3>"
            "</li>\n<li><mk-4>If using headless Chrome, change"
            " HeadlessChrome to Chrome in the User Agent.</mk-4></li>\n"
            "<li><mk-5>If using a custom user_data_dir, don't let that"
            " folder be used with non-UC-Mode Chrome.</mk-5></li>\n"
            "<li><mk-6>Disconnect chromedriver briefly from Chrome before"
            " loading websites with detection services.</mk-6></li>\n"
            "</ul>"
        )
        self.add_slide(
            "Requirements, continued... / <b>Good news:</b><hr />\n"
            "<h3><mk-0>Most of those things are already done automatically"
            " when using UC Mode with default settings.</mk-0></h3>\n"
            "<h4><mk-1>The part that's your responsibility, (if setting a"
            " custom <code>user_data_dir</code>), is making sure that"
            " the u_d_d is only used by UC Mode Chrome instances. If you"
            ' "cross the streams", UC Mode can be detected.</mk-1></h4><div />'
            "<h4><mk-2>(UC Mode takes care of the other requirements.)</mk-2>"
            "</h4>"
        )
        self.add_slide(
            "<h4>With those things done, your bot can appear human.</h4>\n"
            "<h5>But if anyone looks too closely at what your bot does,<br />"
            'it may raise suspicion, even if already marked "not a bot".</h5>',
            image="https://seleniumbase.io/other/other_anti_bots.jpg",
        )
        self.add_slide(
            "<h4><mk-0>There are additional methods that you can use"
            " to have a better experience when using UC Mode:</mk-0></h4>\n"
            "<h6><br /><mk-1>Note that <code><b>driver.get(url)</b></code> has"
            " been modified from the original to<br />reconnect automatically"
            " if a web page is using bot-detection software.</mk-1></h6>"
            "<hr /><br />",
            code=(
                "driver.default_get(url)\n\n"
                "driver.uc_open(url)\n\n"
                "driver.uc_open_with_tab(url)\n\n"
                "driver.uc_open_with_reconnect(url, reconnect_time)\n\n"
                'driver.uc_click(selector, by="css selector", timeout=7)\n'
            ),
        )
        self.add_slide(
            "<h4>There are additional methods that you can use"
            " to have a better experience when using UC Mode:</h4>"
            "<h6><br /><mark>Since <code><b>driver.get(url)</b></code> has"
            " been modified, <code><b>driver.default_get(url)</b></code>"
            " exists to do a regular <code><b>get(url)</b></code>,"
            " which may be useful if revisiting a website.</mark></h6>"
            "<hr /><br />",
            code=(
                "<mark>driver.default_get(url)</mark>\n\n"
                "driver.uc_open(url)\n\n"
                "driver.uc_open_with_tab(url)\n\n"
                "driver.uc_open_with_reconnect(url, reconnect_time)\n\n"
                'driver.uc_click(selector, by="css selector", timeout=7)\n'
            ),
        )
        self.add_slide(
            "<h4>There are additional methods that you can use"
            " to have a better experience when using UC Mode:</h4>"
            "<h6><br /><mark><code><b>driver.uc_open(url)</b></code> will"
            " open a URL in the same tab with a disconnect.<br />"
            "(This might not be enough to bypass detection.)</mark></h6>"
            "<hr /><br />",
            code=(
                "driver.default_get(url)\n\n"
                "<mark>driver.uc_open(url)</mark>\n\n"
                "driver.uc_open_with_tab(url)\n\n"
                "driver.uc_open_with_reconnect(url, reconnect_time)\n\n"
                'driver.uc_click(selector, by="css selector", timeout=7)\n'
            ),
        )
        self.add_slide(
            "<h4>There are additional methods that you can use"
            " to have a better experience when using UC Mode:</h4>\n"
            "<h6><br /><mark><code><b>driver.uc_open_with_tab(url)</b></code>"
            " opens a URL in a new tab with a disconnect. Similar to the new"
            " <code><b>driver.get(url)</b></code>, but without the pre-check."
            "</mark></h6><hr /><br />",
            code=(
                "driver.default_get(url)\n\n"
                "driver.uc_open(url)\n\n"
                "<mark>driver.uc_open_with_tab(url)</mark>\n\n"
                "driver.uc_open_with_reconnect(url, reconnect_time)\n\n"
                'driver.uc_click(selector, by="css selector", timeout=7)\n'
            ),
        )
        self.add_slide(
            "<h4>There are additional methods that you can use"
            " to have a better experience when using UC Mode:</h4>\n"
            "<h6><br /><code><b>driver.uc_open_with_tab(url)</b></code> opens"
            " a URL in a new tab with a disconnect. Similar to the new"
            " <code><b>driver.get(url)</b></code>, but without the pre-check."
            "</h6><hr /><br />\n"
            "<h6><mark>As a reminder, the <code><b>driver.get(url)</b></code>"
            " pre-check checks to see if a URL has bot-detection software"
            " on it before opening the URL in a new tab with a disconnect."
            "</mark><br /></h6><div /><div />\n"
            "<h6><mark>This pre-check is done using"
            " <code><b>requests.get(URL)</b></code><br />before opening"
            " a URL in the <code>UC Mode</code> web browser.</mark></h6>"
            "<h5><mark>If the response code is a"
            ' <code><b>"403"</b></code> (Forbidden),<br />'
            "then the URL is opened with a <code>disconnect</code>."
            "</mark></h5>"
        )
        self.add_slide(
            "<h4><b>Customizing the default disconnect/reconnect time</b></h4>"
            "<hr />\n"
            "<p>Here's a method for a custom reconnect time<br />"
            "when opening a page that tries to detect bots:</p>"
            "<pre><mk-0>driver.uc_open_with_reconnect(url, reconnect_time)"
            "</mk-0></pre>"
            "<h6>(The default reconnect_time is slightly more than 2 seconds.)"
            "</h6><hr /><br />",
            code=(
                "# Example:\n"
                "<mk-1>driver.uc_open_with_reconnect(\n"
                '    "https://nowsecure.nl/#relax", reconnect_time=6\n)</mk-1>'
                "\n\n"
                "# Short form example:\n"
                "<mk-2>driver.uc_open_with_reconnect("
                '"https://nowsecure.nl/#relax", 6)</mk-2>\n'
            ),
        )
        self.add_slide(
            "<h4><b>Clicking with a disconnect/reconnect</b></h4><hr />\n"
            "<p>If your bot needs to click a button on a website that has"
            " anti-bot services, you might be able to do it with this special"
            " method, which forces a short disconnect:</p>\n"
            "<pre><mk-0>driver.uc_click(selector)</mk-0></pre>"
            '<h6>(Defaults: <code>by="css selector", timeout=7</code>)</h6>'
            "<hr /><br />\n",
            code=(
                "# Examples:\n"
                '<mk-1>driver.uc_click("button")\n\n'
                'driver.uc_click("button#id", timeout=10)</mk-1>\n'
            ),
        )
        self.add_slide(
            "<h2>Links to UC Mode code</h2><hr /><br /><ul>\n"
            '<li><a href="https://github.com/seleniumbase/SeleniumBase'
            '/blob/master/examples/verify_undetected.py" target="_blank">'
            'SeleniumBase/examples/verify_undetected.py</a></li><br />\n'
            '<li><a href="https://github.com/seleniumbase/SeleniumBase'
            '/blob/master/examples/uc_cdp_events.py" target="_blank">'
            'SeleniumBase/examples/uc_cdp_events.py</a></li><br />\n'
            '<li><a href="https://github.com/seleniumbase/SeleniumBase'
            '/blob/master/examples/raw_uc_mode.py" target="_blank">'
            'SeleniumBase/examples/raw_uc_mode.py</a></li>'
            "<br />\n</ul>\n",
        )
        self.add_slide(
            "<h2>Things to keep in mind</h2><hr /><ul>\n"
            "<li>You may need to adjust default settings<br />"
            "for your bot to remain undetected.</li><br />\n"
            "<li>Once your bot enters a website,<br />"
            "it should continue to act accordingly.</li><br />\n"
            "<li>Improvise if your bot makes any mistakes.</li><br />\n"
            "<li>Your bot should look human to avoid detection.</li></ul>\n",
        )
        self.add_slide(
            "<h2>Ethical concerns</h2><hr /><ul>\n"
            "<li>Don't use bots for evil purposes.</li><br />\n"
            "<li>Do use bots with honorable intentions.</li><br />\n"
            "<li>Do use bots for automating tedious manual tasks.</li><br />\n"
            "<li>Do take the time to train & configure your bots.</li></ul>\n",
        )
        self.add_slide(
            "<h2>🔹 Final remarks 🔹</h2><div /><hr /><h4><br /><ul>\n"
            "<li>Not all bots are created equal.</li><br />\n"
            "<li>SeleniumBase UC Mode lets bots appear human.</li><br />\n"
            "<li>Visit SeleniumBase on GitHub for more info:\n"
            "https://github.com/seleniumbase/SeleniumBase</li></ul></h4>\n",
        )
        self.add_slide(
            "<h3>❓ Questions? ❓</h3>"
            "<h5>https://github.com/seleniumbase/SeleniumBase/discussions</h5>"
            "<br /><h3>📌 Found a bug? 🐞</h3><h5>"
            "https://github.com/seleniumbase/SeleniumBase/issues</h5><hr />"
            "<br /><h4>🔰 Perfection takes practice. Keep iterating! 🔰</h4>"
        )
        self.add_slide(
            "<h1>The End</h1>",
            image="https://seleniumbase.io/other/sb_github.png"
        )
        self.begin_presentation(filename="uc_presentation.html")
